import React, { Component, useState } from 'react'
import { useEffect } from 'react'

/* 
需求: 模拟请求获取课程列表动态显示
		服务器返回的课程列表数据:
			[
				{id: 1, name: 'JS基础'},
				{id: 2, name: 'JS高级'},
				{id: 3, name: 'React'},
				{id: 4, name: 'Vue'},
				{id: 5, name: '小程序'}
			]
如何模拟发请求?  setTimeout
在哪发请求?  componentDidMount中发 => 使用useEffect
设计state数据: 课程列表的数据: courseList = []   => 使用useState
*/
// 如果放在组件外面, 更新渲染时不会重新执行, 得不到最新的值
// const [msg, setMsg] = useState('atguigu') // 1 + n

export default function HookTest ({count, setCount}) {
  // setMsg是更新内部msg状态数据的函数
  // 一旦调用setMsg函数 => 触发组件函数重新调用 (重新渲染组件) 
  //    => 重新执行useState()得到的就是新的msg
 
   const [msg, setMsg] = useState('atguigu') // 1 + n


  // 初始化课程列表的状态数据
  // if () {
    const [courseList, setCourseList] = useState([])
  // }

  // 使用useEffect去模拟didMount => 发请求获取数据
  // useEffect(() => {}, []) // effect回调就相当于didMount   只执行一次
  useEffect(()=> {
    // console.log('effect回调')
    // 模拟请求获取列表数据显示
    // setTimeout(() => {
    //   // 后台返回的数据
    //   const result = [
		// 		{id: 1, name: 'JS基础'},
		// 		{id: 2, name: 'JS高级'},
		// 		{id: 3, name: 'React'},
		// 		{id: 4, name: 'Vue'},
		// 		{id: 5, name: '小程序'}
		// 	]
    //   // 更新state => 界面就会自动更新显示
    //   setCourseList(result) // 更新courseList

    // }, 3000)
  }, [])
  // 1 + n
  // effect回调会被指定多次 => 只用第一次指定的effect回调

  /* 
  测试useEffect使用
  */
  // effect回调 => didMount
  /* useEffect(() => {
    console.log('effect1 []')
  }, [])
  // effect回调 => didMount + didUpdate (msg变化)
  useEffect(() => {
    console.log('effect2 [msg]')
  }, [msg]) // 监视数组中msg的变化
  // effect回调 => didMount + didUpdate (msg变化或者count变化)
  useEffect(() => {
    console.log('effect3 [msg, count]')
  }, [msg, count]) // 监视数组中msg和count的变化
  // effect回调 => didMount + didUpdate  (任何props或state变化)
  useEffect(() => {
    console.log('effect4')
  }) // 监视当前组件的所有state和props数据的变化
  // effect回调 => didMount +   effect回调返回的函数 => willUnmount
  useEffect(() => {
    console.log('effect5 []')
    // 组件卸载时调用
    return () => {
      console.log('effect5 返回的函数')
    }
  }, []) // 注意要放[] */


  // 需求: 3s后自动更新一个msg
  useEffect(() => {
    setTimeout(() => {
      console.log(msg) // 总是取到的是初始状态值
      // 根据原有state数据来计算产生新数据, 当前写法就不合适
      // setMsg(msg + '--') // 初始状态数据下更新的   ?

      /* 
      setXxx(新值)
      setXxx(value => 根据value产生新值)
      React会将内部保存的最新state数据传递给value, 函数返回值作为最新的state值更新内部数据
       */
      setMsg(msg => msg + '--') // msg总是内部最新的
    }, 3000)
  }, [])



  console.log('HookTest', msg)
  return (
    <div style={{border: '1px solid gray'}}>
      <h3>LifeTest组件</h3>  
      <p>state.msg: {msg}</p>
      <p>props.count: {count}</p>

      <button onClick={() => setMsg(msg + '++')}>更新msg</button>
      <button onClick={() => setCount(count + 2)}>更新父组件的count</button>

      <hr />

      <ul>
        {
          // 遍历显示课程列表
          courseList.map(course => <li key={course.id}>{course.name}</li>)
        }
      </ul>

    </div>
  )
}

/* 没有了以前很模式代码: 固定写法的代码 */

/* function fn1() {
  var a = 2
  function fn2() {
    a++
    console.log(a)
  }
  return fn2
}
const fn = fn1()
fn() // 3
fn() // 4 */